<template>
  <div class="chat-view-container" @drop="handleDrop" @dragover="handleDragOver" @dragleave="handleDragLeave"
    :class="{ 'drag-over': isDragOver }">
    <el-container>
      <el-header class="header">
        <div class="header-content">
          <el-button @click="$router.push('/')" icon="ArrowLeft" type="text">
            返回
          </el-button>
          <h2>{{ room?.name || '聊天室' }}</h2>
          <div class="room-info">
            <span>{{ onlineCount }}人在线</span>
            <el-button v-if="room?.userRole === 'owner'" type="text" @click="showSettings = true">
              设置
            </el-button>
            <el-button type="text" @click="showDebug = !showDebug">
              调试
            </el-button>
          </div>
        </div>
      </el-header>

      <el-main class="main">
        <div class="chat-layout">
          <div v-if="showDebug" class="debug-panel">
            <h4>调试信息</h4>
            <p>WebSocket连接状态: {{ socketService.isConnected() ? '已连接' : '未连接' }}</p>
            <p>当前用户: {{ authStore.user?.username }}</p>
            <p>聊天室ID: {{ roomId }}</p>
            <p>消息数量: {{ messages.length }}</p>
            <p>在线人数: {{ onlineCount }}</p>
            <p>总成员数: {{ room?._count?.users || 0 }}</p>
            <el-button @click="testSendMessage" size="small">测试发送消息</el-button>
            <el-button @click="testJoinRoom" size="small">测试加入聊天室</el-button>
          </div>

          <div class="messages-container" ref="messagesContainer">
            <div v-for="message in messages" :key="message.id" class="message"
              :class="{ 'own-message': message.sender.id === authStore.user?.id }">
              <div class="message-avatar">
                <el-avatar :size="40">{{ message.sender.username.charAt(0) }}</el-avatar>
              </div>
              <div class="message-content">
                <div class="message-header">
                  <span class="username">{{ message.sender.username }}</span>
                  <span class="time">{{ formatTime(message.createdAt) }}</span>
                </div>

                <!-- 文件消息 -->
                <div v-if="message.type === 'file'" class="file-message">
                  <div class="file-info">
                    <div class="file-icon">
                      <el-icon v-if="message.fileType === 'image'">
                        <Picture />
                      </el-icon>
                      <el-icon v-else-if="message.fileType === 'video'">
                        <VideoPlay />
                      </el-icon>
                      <el-icon v-else-if="message.fileType === 'audio'">
                        <Headset />
                      </el-icon>
                      <el-icon v-else>
                        <Document />
                      </el-icon>
                    </div>
                    <div class="file-details">
                      <div class="file-name">{{ message.fileName }}</div>
                      <div class="file-size">{{ formatFileSize(message.fileSize) }}</div>
                    </div>
                    <el-button type="primary" size="small" @click="downloadFile(message)">
                      下载
                    </el-button>
                  </div>

                  <!-- 图片预览 -->
                  <div v-if="message.fileType === 'image'" class="image-preview">
                    <img :src="getFileUrl(message.filePath)" :alt="message.fileName" @click="openImagePreview(message)"
                      @load="handleImageLoad" />
                  </div>

                  <!-- 视频预览 -->
                  <div v-if="message.fileType === 'video'" class="video-preview">
                    <video controls :src="getFileUrl(message.filePath)">
                      您的浏览器不支持视频播放
                    </video>
                  </div>

                  <!-- 音频预览 -->
                  <div v-if="message.fileType === 'audio'" class="audio-preview">
                    <audio controls :src="getFileUrl(message.filePath)">
                      您的浏览器不支持音频播放
                    </audio>
                  </div>
                </div>

                <!-- 文本消息 -->
                <div v-else class="message-text" style="white-space: pre-wrap;">{{ message.content }}</div>
              </div>
            </div>
            <div ref="bottomAnchor" style="height: 1px;"></div>
          </div>

          <div class="input-container">
            <div class="input-toolbar">
              <el-button type="text" icon="Picture" @click="triggerFileUpload('image')" title="发送图片" />
              <el-button type="text" icon="VideoPlay" @click="triggerFileUpload('video')" title="发送视频" />
              <el-button type="text" icon="Headset" @click="triggerFileUpload('audio')" title="发送音频" />
              <el-button type="text" icon="Document" @click="triggerFileUpload('file')" title="发送文件" />
            </div>

            <el-input v-model="newMessage" placeholder="输入消息..." @keydown="handleKeyDown" :disabled="!room || sending"
              type="textarea" :rows="1" :autosize="{ minRows: 1, maxRows: 4 }">
              <template #append>
                <el-button @click="sendMessage" :disabled="!newMessage.trim() || sending" :loading="sending">
                  {{ sending ? '发送中...' : '发送' }}
                </el-button>
              </template>
            </el-input>

            <!-- 文件上传输入框（隐藏） -->
            <input ref="fileInput" type="file" style="display: none" @change="handleFileSelect" multiple />

            <!-- 文件预览区域 -->
            <div v-if="selectedFiles.length > 0" class="file-preview">
              <div v-for="(file, index) in selectedFiles" :key="index" class="file-item">
                <div class="file-info">
                  <span class="file-name">{{ file.name }}</span>
                  <span class="file-size">{{ formatFileSize(file.size) }}</span>
                </div>
                <el-button type="text" icon="Close" @click="removeFile(index)" size="small" />
              </div>
              <el-button @click="sendFiles" :loading="sending" type="primary" size="small">
                发送文件
              </el-button>
            </div>
          </div>
        </div>
      </el-main>
    </el-container>

    <!-- 聊天室设置对话框 -->
    <el-dialog v-model="showSettings" title="聊天室设置" width="500px">
      <el-form :model="settingsForm" label-width="100px">
        <el-form-item label="聊天室名称">
          <el-input v-model="settingsForm.name" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="settingsForm.description" type="textarea" />
        </el-form-item>
        <el-form-item label="是否公开">
          <el-switch v-model="settingsForm.isPublic" />
        </el-form-item>
        <el-form-item label="是否可搜索">
          <el-switch v-model="settingsForm.isSearchable" />
        </el-form-item>
        <el-form-item label="最大人数">
          <el-input-number v-model="settingsForm.maxUsers" :min="1" :max="1000" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showSettings = false">取消</el-button>
        <el-button type="primary" @click="updateRoomSettings" :loading="updating">
          保存
        </el-button>
      </template>
    </el-dialog>

    <!-- 图片预览组件 -->
    <ImagePreview ref="imagePreviewRef" :images="imageMessages" />

    <!-- 拖放提示 -->
    <transition name="fade">
      <div v-if="isDragOver" class="drag-drop-hint">
        <div class="hint-content">
          <el-icon class="hint-icon">
            <Upload />
          </el-icon>
          <div class="hint-text">拖放到此处上传文件</div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, onUnmounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useAuthStore } from '@/stores/auth'
import { chatroomAPI, messageAPI } from '@/services/api'
import socketService from '@/services/socket'
import { uploadAPI } from '@/services/api'
import ImagePreview from '@/components/ImagePreview.vue'
import { Upload } from '@element-plus/icons-vue'
import api, { getFileUrl } from '../services/api';

const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()

const roomId = route.params.roomId as string
const room = ref(null)
const messages = ref([])
const newMessage = ref('')
const messagesContainer = ref()
const showSettings = ref(false)
const updating = ref(false)
const showDebug = ref(false)
const sending = ref(false)
const selectedFiles = ref([])
const fileInput = ref()
const onlineCount = ref(0)
const imagePreviewRef = ref()
const isDragOver = ref(false)
const dragOverTimeout = ref(null)
const isAtBottom = ref(true)
const bottomAnchor = ref<HTMLElement | null>(null)
let resizeObserver: ResizeObserver | null = null

// 收集所有图片消息
const imageMessages = computed(() => {
  return messages.value
    .filter(msg => msg.type === 'file' && msg.fileType === 'image')
    .map(msg => ({
      url: getFileUrl(msg.filePath),
      fileName: msg.fileName,
      fileSize: formatFileSize(msg.fileSize)
    }))
})

const settingsForm = reactive({
  name: '',
  description: '',
  isPublic: true,
  isSearchable: true,
  maxUsers: 100
})

// 加载聊天室信息
async function loadRoom() {
  try {
    const response = await chatroomAPI.getRoom(roomId)
    room.value = response.data

    // 初始化在线人数为当前成员数
    onlineCount.value = room.value._count?.users || 0

    // 更新设置表单
    Object.assign(settingsForm, {
      name: room.value.name,
      description: room.value.description,
      isPublic: room.value.isPublic,
      isSearchable: room.value.isSearchable,
      maxUsers: room.value.maxUsers
    })
  } catch (error) {
    ElMessage.error('聊天室不存在或无权访问')
    router.push('/')
  }
}

// 加载消息历史
async function loadMessages() {
  try {
    const response = await messageAPI.getMessages(roomId)
    messages.value = response.data.messages
    await nextTick()
    scrollToBottom()
    // 图片等资源加载完成后再补偿一次
    await waitForImagesLoaded()
    scrollToBottom()
  } catch (error) {
    // 静默处理错误
  }
}

// 发送消息
async function sendMessage() {
  if (!newMessage.value.trim() || !room.value || sending.value) return

  const messageContent = newMessage.value

  sending.value = true

  try {
    // 检查WebSocket连接状态
    if (!socketService.isConnected()) {
      ElMessage.error('连接已断开，正在重新连接...')
      socketService.connect(authStore.token)
      return
    }

    // 通过WebSocket发送消息
    socketService.sendMessage(parseInt(roomId), messageContent, 'text')

    // 清空输入框
    newMessage.value = ''
  } catch (error) {
    ElMessage.error('发送失败，请重试')
  } finally {
    sending.value = false
  }
}

// 处理键盘事件
function handleKeyDown(event: KeyboardEvent) {
  if (event.key === 'Enter' && !event.shiftKey) {
    event.preventDefault()
    sendMessage()
  }
}

// 更新聊天室设置
async function updateRoomSettings() {
  updating.value = true
  try {
    await chatroomAPI.updateRoom(roomId, settingsForm)
    ElMessage.success('设置已更新')
    showSettings.value = false
    await loadRoom()
  } catch (error: any) {
    ElMessage.error(error.response?.data?.message || '更新失败')
  } finally {
    updating.value = false
  }
}

// 滚动到底部
function scrollToBottom() {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

// 判断是否在底部（阈值 20px）
function updateIsAtBottom() {
  const el = messagesContainer.value as HTMLElement | undefined
  if (!el) return
  const distanceToBottom = el.scrollHeight - (el.scrollTop + el.clientHeight)
  isAtBottom.value = distanceToBottom <= 20
}

// 等待当前容器中图片加载完成
function waitForImagesLoaded(timeoutMs = 2000): Promise<void> {
  return new Promise((resolve) => {
    const el = messagesContainer.value as HTMLElement | undefined
    if (!el) return resolve()
    const imgs = Array.from(el.querySelectorAll('img')) as HTMLImageElement[]
    const pending: HTMLImageElement[] = imgs.filter(img => !(img.complete && img.naturalHeight !== 0))
    if (pending.length === 0) return resolve()

    let resolved = false
    const done = () => { if (!resolved) { resolved = true; resolve() } }
    const onAny = () => {
      // 若全部完成，则 resolve
      if (pending.every(img => img.complete)) done()
    }
    pending.forEach(img => {
      img.addEventListener('load', onAny, { once: true })
      img.addEventListener('error', onAny, { once: true })
    })
    setTimeout(done, timeoutMs)
  })
}

// 图片单张加载完成时，若粘底则补偿滚动
function handleImageLoad() {
  if (isAtBottom.value) nextTick(() => scrollToBottom())
}

// 格式化时间
function formatTime(time: string) {
  return new Date(time).toLocaleString()
}

// 测试发送消息
function testSendMessage() {
  socketService.sendMessage(parseInt(roomId), '这是一条测试消息 ' + new Date().toLocaleTimeString(), 'text')
}

// 测试加入聊天室
function testJoinRoom() {
  socketService.joinRoom(parseInt(roomId))
}

// 初始化 WebSocket 连接
function initSocket() {
  socketService.connect(authStore.token)

  socketService.onConnect(() => {
    setTimeout(() => {
      socketService.joinRoom(parseInt(roomId))
    }, 200); // 延迟200ms，确保 handleConnection 完成
  })

  socketService.onNewMessage((message) => {
    messages.value.push(message)
    nextTick(() => {
      if (message.type === 'file' && message.fileType === 'image') {
        // 等图片渲染后再判断是否需要粘底
        if (isAtBottom.value) scrollToBottom()
      } else {
        if (isAtBottom.value) scrollToBottom()
      }
    })
  })

  socketService.onDisconnect(() => {
  })

  socketService.onUserJoin((_data) => {
    onlineCount.value++
  })

  socketService.onUserLeave((_data) => {
    onlineCount.value = Math.max(0, onlineCount.value - 1)
  })
}

// 触发文件上传
function triggerFileUpload(type: string) {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = getAcceptType(type)
  input.multiple = true
  input.style.display = 'none'

  input.addEventListener('change', (event) => {
    handleFileSelect(event)
  })

  document.body.appendChild(input)
  input.click()
  document.body.removeChild(input)
}

// 处理文件选择
function handleFileSelect(event: Event) {
  const target = event.target as HTMLInputElement
  if (target.files) {
    const files = Array.from(target.files)
    selectedFiles.value.push(...files)
  }
}

// 获取文件类型
function getAcceptType(type: string) {
  switch (type) {
    case 'image':
      return 'image/*'
    case 'video':
      return 'video/*'
    case 'audio':
      return 'audio/*'
    case 'file':
      return '*/*'
    default:
      return '*/*'
  }
}

// 移除文件
function removeFile(index: number) {
  selectedFiles.value.splice(index, 1)
}

// 打开图片预览
function openImagePreview(message: any) {
  const imageIndex = imageMessages.value.findIndex(img =>
    img.fileName === message.fileName && img.url === getFileUrl(message.filePath)
  )

  if (imageIndex !== -1 && imagePreviewRef.value) {
    imagePreviewRef.value.openPreview(imageIndex)
  }
}

// 处理拖放事件
function handleDragOver(event: DragEvent) {
  event.preventDefault()

  // 清除之前的超时
  if (dragOverTimeout.value) {
    clearTimeout(dragOverTimeout.value)
    dragOverTimeout.value = null
  }

  isDragOver.value = true
}

function handleDragLeave(event: DragEvent) {
  event.preventDefault()

  // 只有当鼠标离开整个页面时才隐藏拖放提示
  if (event.relatedTarget === null ||
    (event.relatedTarget instanceof Node && !document.contains(event.relatedTarget as Node))) {
    // 添加延迟隐藏，避免在元素间移动时频繁闪烁
    dragOverTimeout.value = setTimeout(() => {
      isDragOver.value = false
      dragOverTimeout.value = null
    }, 100)
  }
}

function handleDrop(event: DragEvent) {
  event.preventDefault()
  isDragOver.value = false

  const files = event.dataTransfer?.files
  if (files && files.length > 0) {
    // 过滤掉非文件类型的拖放（如文本等）
    const fileList = Array.from(files).filter(file => file.type !== '')
    if (fileList.length > 0) {
      selectedFiles.value.push(...fileList)
      ElMessage.success(`已添加 ${fileList.length} 个文件到待上传列表`)
    }
  }
}

// 下载文件
async function downloadFile(message: any) {
  try {
    const fileUrl = getFileUrl(message.filePath)
    const response = await api.get(fileUrl, {
      responseType: 'blob'
    })

    const url = window.URL.createObjectURL(new Blob([response.data]))
    const link = document.createElement('a')
    link.href = url
    link.setAttribute('download', message.fileName)
    document.body.appendChild(link)
    link.click()
    link.remove()
    window.URL.revokeObjectURL(url)

    ElMessage.success('文件下载开始')
  } catch (error) {
    ElMessage.error('下载失败')
  }
}

// 格式化文件大小
function formatFileSize(bytes: number) {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 发送文件
async function sendFiles() {
  if (selectedFiles.value.length === 0) return

  sending.value = true

  try {
    // 逐个上传文件
    for (const file of selectedFiles.value) {
      try {
        // 上传文件到服务器
        const uploadResponse = await uploadAPI.uploadFile(file)

        // 通过WebSocket发送文件消息
        socketService.sendMessage(parseInt(roomId), '', 'file', undefined, {
          fileId: uploadResponse.data.id,
          fileName: uploadResponse.data.name,
          fileType: uploadResponse.data.type,
          fileSize: uploadResponse.data.size,
          fileUrl: uploadResponse.data.url
        })
      } catch (error) {
        const message = error?.response?.data?.message
        ElMessage.error(`文件 ${file.name} 上传失败${message ? `：${message}` : ""}`)
      }
    }

    // 清空文件列表
    selectedFiles.value = []
  } catch (error) {
    ElMessage.error('发送失败，请重试')
  } finally {
    sending.value = false
  }
}

onMounted(async () => {
  try {
    // 确保用户信息已加载
    if (!authStore.user && authStore.token) {
      await authStore.fetchProfile()
    }

    await loadRoom()
    await loadMessages()

    // 在用户信息和聊天室信息加载完成后再初始化WebSocket
    initSocket()

    // 监听滚动，更新粘底状态
    if (messagesContainer.value) {
      messagesContainer.value.addEventListener('scroll', updateIsAtBottom)
    }

    // 监听内容尺寸变化，若处于粘底则继续保持粘底
    if ('ResizeObserver' in window && messagesContainer.value) {
      resizeObserver = new ResizeObserver(() => {
        if (isAtBottom.value) scrollToBottom()
      })
      resizeObserver.observe(messagesContainer.value)
    }
  } catch (error) {
    ElMessage.error('初始化失败，请刷新页面重试')
  }
})

onUnmounted(() => {
  socketService.disconnect()

  // 清理拖放超时定时器
  if (dragOverTimeout.value) {
    clearTimeout(dragOverTimeout.value)
    dragOverTimeout.value = null
  }

  // 清理滚动监听与 ResizeObserver
  if (messagesContainer.value) {
    messagesContainer.value.removeEventListener('scroll', updateIsAtBottom)
  }
  if (resizeObserver && messagesContainer.value) {
    resizeObserver.unobserve(messagesContainer.value)
  }
})
</script>

<style scoped>
.chat-view-container {
  height: 100vh;
  height: 100dvh;
  /* 使用动态视口高度，兼容 Safari */
  position: relative;
  display: flex;
  flex-direction: column;
}

.chat-view-container.drag-over {
  background: rgba(64, 158, 255, 0.1);
  outline: 2px dashed #409eff;
  outline-offset: -10px;
}

.drag-drop-hint {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2000;
  backdrop-filter: blur(5px);
}

.hint-content {
  background: rgba(255, 255, 255, 0.95);
  padding: 40px 60px;
  border-radius: 16px;
  text-align: center;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  border: 2px dashed #409eff;
}

.hint-icon {
  font-size: 48px;
  color: #409eff;
  margin-bottom: 16px;
}

.hint-text {
  font-size: 18px;
  font-weight: 600;
  color: #409eff;
}

/* 动画效果 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.header {
  background: #fff;
  border-bottom: 1px solid #e4e7ed;
  padding: 0;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;
  padding: 0 20px;
}

.header-content h2 {
  margin: 0;
  color: #333;
}

.room-info {
  display: flex;
  align-items: center;
  gap: 16px;
}

/* 基础布局：不强制固定高度，交由媒体查询细分 */
.main {
  padding: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* 允许子元素正确收缩 */
}

/* 确保消息列表可滚动，输入区域可见 */
.chat-layout {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.messages-container {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background: #f5f7fa;
  min-height: 0;
}

.message {
  display: flex;
  margin-bottom: 20px;
  gap: 12px;
}

.message.own-message {
  flex-direction: row-reverse;
}

.message-content {
  max-width: 70%;
}

.message-header {
  margin-bottom: 4px;
}

.username {
  font-weight: 600;
  font-size: 14px;
  color: #333;
}

.time {
  font-size: 12px;
  color: #999;
  margin-left: 8px;
}

.message-text {
  background: #fff;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  word-wrap: break-word;
  line-height: 1.4;
  white-space: pre-wrap;
}

.own-message .message-text {
  background: #409eff;
  color: #fff;
}

.input-container {
  padding: 20px;
  background: #fff;
  border-top: 1px solid #e4e7ed;
  flex-shrink: 0;
}

.debug-panel {
  padding: 20px;
  background: #fff;
  border-bottom: 1px solid #e4e7ed;
}

.debug-panel h4 {
  margin-bottom: 16px;
}

.debug-panel p {
  margin-bottom: 8px;
}

.input-toolbar {
  margin-bottom: 10px;
}

.input-toolbar button {
  margin-right: 10px;
}

.file-preview {
  margin-top: 10px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
  max-height: 40vh;
  /* 防止文件预览过高挤压消息区 */
  overflow: auto;
}

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 5px;
}

.file-info {
  display: flex;
  align-items: center;
}

.file-name {
  margin-right: 10px;
}

.file-size {
  font-size: 12px;
  color: #999;
}

/* 聊天输入框样式 */
:deep(.el-textarea__inner) {
  border-radius: 20px;
  padding: 8px 16px;
  resize: none;
  font-family: inherit;
}

:deep(.el-input-group__append) {
  border-radius: 0 20px 20px 0;
  border-left: none;
}

:deep(.el-input-group__append .el-button) {
  border-radius: 0 20px 20px 0;
  border: none;
  height: 100%;
}

.image-preview img {
  max-width: 100%;
  max-height: 300px;
  border-radius: 8px;
  cursor: pointer;
}

.video-preview video {
  max-width: 100%;
  max-height: 300px;
  border-radius: 8px;
}

.audio-preview audio {
  width: 300px;
}

.own-message .file-message {
  background: #409eff;
  color: #fff;
}

.own-message .file-size {
  color: rgba(255, 255, 255, 0.8);
}

.own-message .file-icon {
  color: #fff;
}

.file-size {
  font-size: 12px;
  color: #999;
}

.file-message {
  background: #fff;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  margin-bottom: 10px;
}

.file-info {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.file-icon {
  margin-right: 10px;
  font-size: 20px;
  color: #409eff;
}

.file-details {
  flex: 1;
  margin-right: 10px;
}

.file-name {
  font-weight: 600;
  margin-bottom: 4px;
  word-break: break-all;
}

/* 聊天输入框样式 */
:deep(.el-textarea__inner) {
  border-radius: 20px;
  padding: 8px 16px;
  resize: none;
  font-family: inherit;
}

:deep(.el-input-group__append) {
  border-radius: 0 20px 20px 0;
  border-left: none;
}

:deep(.el-input-group__append .el-button) {
  border-radius: 0 20px 20px 0;
  border: none;
  height: 100%;
}

/* Safari 兼容性修复 */
@supports (-webkit-touch-callout: none) {
  .chat-view-container {
    height: -webkit-fill-available;
  }

  .main {
    height: calc(-webkit-fill-available - 60px);
  }
}

/* 移动端：锁定视口高度，避免页面级滚动 */
@media screen and (max-width: 768px) {
  .chat-view-container {
    height: 100vh;
    height: 100dvh;
    height: -webkit-fill-available;
    overflow: hidden;
    /* 防止页面滚动 */
    position: fixed;
    /* 固定定位，防止页面滚动 */
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  }

  .main {
    height: calc(100vh - 60px);
    height: calc(100dvh - 60px);
    height: calc(-webkit-fill-available - 60px);
    overflow: hidden;
    /* 防止内容溢出 */
  }

  .messages-container {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    /* 启用 iOS 平滑滚动 */
  }

  .input-container {
    padding: 15px;
    padding-bottom: max(15px, env(safe-area-inset-bottom));
    /* 支持 iPhone 安全区域 */
  }
}

/* 桌面端：使用 flex 高度填充，不固定 main 高度 */
@media screen and (min-width: 769px) {
  .chat-view-container {
    height: 100vh;
  }

  .main {
    height: auto;
    /* 取消固定高度，交由 flex 布局 */
  }

  .input-container {
    position: static;
    /* 确保不使用 sticky，避免遮挡或脱离文档流 */
    bottom: auto;
    z-index: auto;
    overflow: visible;
  }
}

/* Element Plus 容器在桌面端的高度与布局修正 */
:deep(.el-container) {
  height: 100%;
  display: flex;
  flex-direction: column;
}

:deep(.el-header) {
  flex: 0 0 60px;
  /* 明确头部高度，防止挤压 */
}

:deep(.el-main) {
  flex: 1 1 auto;
  min-height: 0;
  /* 允许内部滚动容器正确计算高度 */
  display: flex;
  flex-direction: column;
}
</style>